package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	
	import away3d.cameras.Camera3D;
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.Scene3D;
	import away3d.containers.View3D;
	import away3d.controllers.HoverController;
	import away3d.debug.AwayStats;
	import away3d.events.AssetEvent;
	import away3d.events.LoaderEvent;
	import away3d.library.AssetLibrary;
	import away3d.loaders.parsers.AWD2Parser;
	import away3d.textures.BitmapTexture;
	
	[SWF(backgroundColor="#000000", frameRate="60", quality="LOW")]
	
	public class AWDViewerLoth extends Sprite
	{
		
		private var modelTexture:BitmapTexture;
		private const DemoColor:Array = [0xffffff, 0x99AAff, 0x222233];
		
		//engine variables
		private var scene:Scene3D;
		private var camera:Camera3D;
		private var view:View3D;
		private var awayStats:AwayStats;
		
		//scene objects
		private var hero:ObjectContainer3D;
		
		private var hoverController:HoverController;
		private var _prevMouseX:Number;
		private var _prevMouseY:Number;
		
		private var MESH_URL:String = "BM.awd";
//		private var MESH_URL:String = "archMage.awd";
		private var assetsThatAreloaded:int = 0;
		private var assetsToLoad:int = 1;
		
		/**
		 * Constructor
		 */
		public function AWDViewerLoth()
		{
			initEngine();
			initLoading();
		}
		
		/**
		 * Initialise the engine
		 */
		private function initEngine():void
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			scene = new Scene3D();
			
			camera = new Camera3D();
			camera.lens.far = 5000;
			camera.lens.near = 20;
			
			view = new View3D();
			view.backgroundColor = DemoColor[2];
			view.scene = scene;
			view.camera = camera;
			
			hoverController = new HoverController(camera);
			hoverController.tiltAngle = 0;
			hoverController.panAngle = 180;
			hoverController.minTiltAngle = -60;
			hoverController.maxTiltAngle = 60;
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, onStageMouseWheel);
			
			addChild(view);
			
			awayStats = new AwayStats(view);
			addChild(awayStats);
			
		}
		
		private function showError(t:String):void
		{
			trace("ERROR: " + t);
		}
		
		/**
		 * Initialise the scene objects
		 */
		private function initLoading():void
		{
			AssetLibrary.enableParser(AWD2Parser);
			AssetLibrary.addEventListener(AssetEvent.ASSET_COMPLETE, onAssetComplete);
			AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
			AssetLibrary.addEventListener(LoaderEvent.LOAD_ERROR, onLoadError);
			AssetLibrary.load(new URLRequest(MESH_URL));
		}
		
		protected function onLoadError(event:LoaderEvent):void
		{
			showError("Error loading: " + event.url);
		}
		
		/**
		 * Listener function for asset complete event on loader
		 */
		private function onAssetComplete(event:AssetEvent):void
		{
			// To not see these names output in the console, comment the
			// line below with two slash'es, just as you see on this line
			trace("Loaded " + event.asset.name + " Name: " + event.asset.name +" type:"+event.asset);
		}
		
		private function onResourceComplete(ev:LoaderEvent):void
		{
			assetsThatAreloaded++;
			// check to see if we have all we need
			if (assetsThatAreloaded == assetsToLoad) {
				setupScene();
			}
		}
		
		private function setupScene():void
		{
			hero = ObjectContainer3D(AssetLibrary.getAsset("cont0"));
			hero.scale(5);
			
			scene.addChild(hero);
			
			hoverController.lookAtObject = hero; // point the camera at the hero
			initListeners(); // get ready for user input
		}
		
		/**
		 * Initialise the listeners
		 */
		private function initListeners():void
		{
			// start calling the
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			// listen for the browser being resized
			stage.addEventListener(Event.RESIZE, onResize);
			onResize();
		}
		
		/**
		 * Navigation and render loop
		 */
		private function onEnterFrame(event:Event):void
		{
			//update character animation
			
			view.render();
		}
		
		/**
		 * stage listener for resize events
		 */
		private function onResize(event:Event = null):void
		{
			view.width = stage.stageWidth;
			view.height = stage.stageHeight;
			awayStats.x = stage.stageWidth - awayStats.width;
		}
		
		private function onStageMouseDown(ev:MouseEvent):void
		{
			_prevMouseX = ev.stageX;
			_prevMouseY = ev.stageY;
		}
		
		private function onStageMouseMove(ev:MouseEvent):void
		{
			if (ev.buttonDown) {
				hoverController.panAngle += (ev.stageX - _prevMouseX);
				hoverController.tiltAngle += (ev.stageY - _prevMouseY);
			}
			
			_prevMouseX = ev.stageX;
			_prevMouseY = ev.stageY;
		}
		
		private function onStageMouseWheel(ev:MouseEvent):void
		{
			hoverController.distance -= ev.delta * 5;
			
			if (hoverController.distance < 100)
				hoverController.distance = 100;
			else if (hoverController.distance > 2000)
				hoverController.distance = 2000;
		}
	}
}
